package cn.cnf.service.impl;

import cn.cnf.common.StringPool;
import cn.cnf.common.enums.RecommendState;
import cn.cnf.common.enums.StateEnum;
import cn.cnf.common.enums.VerifyState;
import cn.cnf.common.exception.CustomException;
import cn.cnf.common.utils.BigDecimalUtil;
import cn.cnf.common.utils.FileUtil;
import cn.cnf.common.utils.UserRequestUtil;
import cn.cnf.config.StaticConfig;
import cn.cnf.entity.*;
import cn.cnf.entity.vo.ComicDetailsInfo;
import cn.cnf.entity.vo.ImageInfo;
import cn.cnf.mapper.ComicMapper;
import cn.cnf.service.*;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.core.toolkit.support.SFunction;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.CollectionUtils;

import java.io.File;
import java.math.BigDecimal;
import java.util.LinkedList;
import java.util.List;
import java.util.UUID;

/**
 * 服务接口实现
 *
 * @author ZhuMeiYi
 * @description
 * @since 2020-12-04 17:12:13
 */
@Slf4j
@RequiredArgsConstructor(onConstructor = @_(@Autowired))
@Service
@Transactional(rollbackFor = {RuntimeException.class, Error.class})
public class ComicServiceImpl extends ServiceImpl<ComicMapper, Comic> implements ComicService {

    private final ComicMapper comicMapper;
    @Autowired
    private ComicDetailsService comicDetailsService;
    @Autowired
    private UserService userService;
    @Autowired
    private MoneyRecordService moneyRecordService;
    @Autowired
    private ComicService comicService;
    @Autowired
    private ChapterService chapterService;
    @Autowired
    private NovelService novelService;

    @Override
    public IPage<Comic> selectPageVo(Integer current, Integer pageSize,String name) {
        // 仅获取审核通过
        LambdaQueryWrapper<Comic> wrapper = new LambdaQueryWrapper<Comic>().eq(Comic::getVerifyState, VerifyState.VERIFIED.getValue())
                .like(name!=null,Comic::getComicName,name);
        Page<Comic> page = new Page<>(current,pageSize);
        return comicMapper.selectPage(page,wrapper);
    }

    @Override
    public ComicDetailsInfo getDetails(String comicId, String chapterId) {
        if (StringUtils.isBlank(comicId)){
            throw new CustomException("没有找到对应漫画");
        }else if (StringUtils.isBlank(chapterId)){
            throw new CustomException("没有找到对应章节");
        }
        Comic comic = comicService.getById(comicId);
        Chapter chapter = chapterService.getById(chapterId);
//        LambdaQueryWrapper<ComicDetails> wrapper = Wrappers.lambdaQuery();
//        wrapper.eq(ComicDetails::getComicId,comicId)
//                .eq(ComicDetails::getComicChapterId,chapterId);
//        ComicDetails comicDetails1 = comicDetailsService.getOne(wrapper);

        ComicDetailsInfo comicDetailsInfo = new ComicDetailsInfo();
        comicDetailsInfo.setComicId(comicId);
        comicDetailsInfo.setComicChapterId(chapterId);
        comicDetailsInfo.setComicName(comic.getComicName());
        comicDetailsInfo.setChapterName(chapter.getChapterName());
        comicDetailsInfo.setNeedMoney(chapter.getNeedMoney());
//        comicDetailsInfo.setComicDetailsId(comicDetails1.getId());

        List<ComicDetails> comicDetails = comicDetailsService.selectDetails(comicId, chapterId);
        LinkedList<ImageInfo> imageInfos = new LinkedList<>();
        for (ComicDetails comicDetail : comicDetails) {
            ImageInfo imageInfo = new ImageInfo();
            imageInfo.setImgPath(comicDetail.getPicPath());
            imageInfo.setSortNum(comicDetail.getSortNum());
            imageInfos.add(imageInfo);
        }
        comicDetailsInfo.setPic(imageInfos);
        return comicDetailsInfo;
    }

    @Override
    public String addOrUpdateComic(Comic comic) {
        // 如果是新增
        if (StringUtils.isBlank(comic.getId())){
            // 设置作者
            User user = userService.findUserByUsername(UserRequestUtil.getCurrentUserName());
            comic.setAuthorId(user.getId());
            comic.setNeedMoney(0);
            comic.setRecommend(0);
//            comic.setState(10);
            comic.setVerifyState(0);
            comic.setCollectNum(0);
            comic.setCommentNum(0);
            comic.setSubscribeNum(0);

        }
        // 新增&修改漫画为审核中状态
        comic.setVerifyState(VerifyState.VERIFYING.getValue());
        // 创建漫画文件夹
        final String localPath = StaticConfig.localPath + StringPool.comicPath+"/" + comic.getId();
        File dest = new File(localPath);
        if (!dest.exists()) {
            dest.mkdir();
        }
        // 保存漫画
        saveOrUpdate(comic);
        return comic.getId();
    }

    @Override
    public String addOrUpdateDetails(ComicDetailsInfo comicDetailsInfo) {
        if (StringUtils.isBlank(comicDetailsInfo.getComicId())){
            throw new CustomException("漫画id为空");
        }
        if (StringUtils.isBlank(comicDetailsInfo.getComicChapterId())){
            throw new CustomException("章节id为空");
        }
        if (comicService.getById(comicDetailsInfo.getComicId())==null){
            throw new CustomException("未找到对应漫画");
        }
        if (chapterService.getById(comicDetailsInfo.getComicChapterId())==null){
            throw new CustomException("未找到对应章节");
        }

        List<ComicDetails> details = new LinkedList<>();
        for (ImageInfo imageInfo : comicDetailsInfo.getPic()) {
            ComicDetails comicDetails = new ComicDetails();
            comicDetails.setComicId(comicDetailsInfo.getComicId());
            comicDetails.setComicChapterId(comicDetailsInfo.getComicChapterId());
            comicDetails.setSortNum(imageInfo.getSortNum());
            comicDetails.setPicPath(imageInfo.getImgPath());
            details.add(comicDetails);
        }
        if (!comicDetailsService.saveOrUpdateBatch(details)) {
            throw new CustomException("保存失败");
        }
        return comicDetailsInfo.getComicChapterId();
    }

    @Override
    public IPage<Comic> searchByName(Integer current, Integer pageSize, String comicName) {

        // 建立查询wrapper
        LambdaQueryWrapper<Comic> wrapper = new LambdaQueryWrapper<Comic>()
                .like(Comic::getComicName, comicName)
                .eq(Comic::getVerifyState,VerifyState.VERIFIED.getValue());

        // 分页
        Page<Comic> page = new Page<>(current, pageSize);
        return comicMapper.selectPage(page, wrapper);
    }

    @Override
    public String delete(String comicId) {
        // 删除漫画
        removeById(comicId);
        // 删除文件
        String path = StaticConfig.localPath + "\\" + comicId;
        FileUtil.deleteDirectory(path);
        return comicId;
    }

    @Override
    public String deleteChapterImg(String comicId, String chapterId) {
        // 如果章节删除成功删除文件
        String path = StaticConfig.localPath + "\\" + comicId + "\\" + chapterId;
        if (FileUtil.deleteDirectory(path)) {
            return chapterId;
        } else {
            throw new CustomException("没有找到对应的图片");
        }


    }

    @Override
    public Integer updateSubscribe(String subscribeId, int number) {
        return comicMapper.updateSubscribe(subscribeId, number);
    }

    @Override
    public BigDecimal adjustComicMoneyById(String comicId, BigDecimal num) {
        Comic comic = getById(comicId);
        BigDecimal result = BigDecimalUtil.safeAdd(comic.getIncome(), num);
        if (BigDecimalUtil.lessThan(result,BigDecimal.ZERO)) {
            throw new CustomException("余额不足");
        } else {
            if (comicMapper.updateIncome(comicId,result)<=0){
                throw new CustomException("收入调整失败");
            }
            return result;
        }
    }

    @Override
    public List<Comic> getPersonalComics(String username) {
        User user = userService.findUserByUsername(username);
        return list(new LambdaQueryWrapper<Comic>().eq(Comic::getAuthorId, user.getId()));
    }

    @Override
    public String recommend(String comicId, RecommendState state) {
        Integer integer = comicMapper.updateRecommend(comicId, state.getValue());
        if (integer<=0) {
            throw new CustomException("更新推荐状态失败");
        }
        return comicId;
    }

    @Override
    public IPage<Comic> getAllRecommend(Integer current, Integer pageSize) {
        LambdaQueryWrapper<Comic> wrapper = new LambdaQueryWrapper<Comic>().eq(Comic::getRecommend, 1);
        // 分页
        Page<Comic> page = new Page<>(current, pageSize);
        return comicMapper.selectPage(page, wrapper);
    }

    @Override
    public IPage<Comic> getVerifying(Integer current, Integer pageSize) {
        Page<Comic> page = new Page<>(current,pageSize);
        return comicMapper.selectVerifyingList(page);
    }

    @Override
    public String comicVerify(String comicId, VerifyState state) {
        if (state == null) {
            throw new CustomException("不存在的状态");
        }
        if (comicMapper.updateVerify(comicId,state.getValue())<=0) {
            throw new CustomException("审核失败");
        }
        return comicId;
    }

    @Override
    public boolean isAuthor(String comicId, String userId) {
        List<Comic> list = list(new LambdaQueryWrapper<Comic>().eq(Comic::getId, comicId).eq(Comic::getAuthorId, userId));
        return !CollectionUtils.isEmpty(list);
    }

    @Override
    public List<Comic> getRecentlyUpdate(Integer current, Integer pageSize) {
        Page<Comic> page = new Page<>(current,pageSize);
        List<Comic> records = page.getRecords();
        for (Comic record : records) {
            if(record.getLastChapterId() == null || record.getVerifyState() == 0 || record.getUpdateTime() == null){

            }
        }

        return comicMapper.getRecentlyUpdate(page);
    }

    @Override
    public IPage<Comic> rank(Integer current, Integer pageSize, SFunction<Comic,Integer> getter) {
        LambdaQueryWrapper<Comic> wrapper = new LambdaQueryWrapper<Comic>().eq(Comic::getVerifyState,1).orderByDesc(getter);
        return comicMapper.selectPage(new Page<>(current, pageSize), wrapper);
    }

    @Override
    public Integer updateCollectNum(String comicId, Integer value) {
        return comicMapper.updateCollectNum(comicId,value);
    }

    @Override
    public Integer updateCommentNum(String comicId, Integer value) {
        return comicMapper.updateCommentNum(comicId,value);
    }

    @Override
    public Integer updateState(String comicId, StateEnum state) {
        if (state==null){
            throw new CustomException("不存在的状态");
        }
        Comic comic = getById(comicId);
        if (comic==null){
            throw new CustomException("漫画不存在");
        }
        User user = userService.getById(comic.getAuthorId());
        if (!user.getUsername().equals(UserRequestUtil.getCurrentUserName())){
            throw new CustomException("非用户本人不能修改状态");
        }
        return comicMapper.updateState(comicId,state.getValue());
    }

    @Override
    public IPage<Comic> getByState(Integer current, Integer pageSize, StateEnum state) {
        LambdaQueryWrapper<Comic> wrapper = new LambdaQueryWrapper<Comic>().eq(Comic::getState, state.getValue());
        return comicMapper.selectPage(new Page<>(current, pageSize), wrapper);
    }

    @Override
    public boolean linkAuthor(JSONObject jsonObject) {
        //comicId 漫画Id，novelId   小说id
        //String comicId,String novelId
        //String uuid = UUID.randomUUID ().toString ().replace ("-","").toUpperCase ();
        //小说表信息设置标志位
        Novel novel = new Novel();
        novel.setSign (jsonObject.getString("comicId"));
        novel.setId (jsonObject.getString("novelId"));
        novelService.updateById (novel);
        //漫画表设置标志位
        Comic comic = new Comic();
        comic.setSign (jsonObject.getString("novelId"));

        comic.setId (jsonObject.getString("comicId"));
        comicService.updateById (comic);
        return true;
    }
}